﻿using ModbusCase.Lib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ModbusCase
{
    /// <summary>
    /// MobusTCP协议测试(自己封装)
    /// </summary>
    public partial class TCPCaseBySelf : Window, INotifyPropertyChanged
    {
        private Socket socket;
        private ModbusTCP modbusTCP;

        public TCPCaseBySelf()
        {
            InitializeComponent();

            DataContext = this; // 上下文

            Connect();

            #region 读取三个输出线圈状态
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        // 每隔1秒读取三个输出线圈
                        ReadOutputStatus();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 数字量输入
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        ReadInputStatus();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 模拟量输出
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        ReadOutputNum();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 模拟量输入
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        ReadInputNum();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 读float
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        ReadFloat();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 读Int
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        ReadInt();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 读Short
            Task.Run(async () =>
            {
                while (true)
                {
                    Dispatcher.Invoke(() =>
                    {
                        ReadShort();
                    });

                    await Task.Delay(1000);
                }
            });
            #endregion

            #region 测试代码
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                // 写多线圈测试
                // modbusTCP.WriteMultipleCoil(0, [true,true,true,false,false,false,false,false,true]);

                // 读32位int测试
                //int[] rst = modbusTCP.ReadRegInt32(FuncCode.ReadHoldingRegisters, 10, 1, Endian.BigEndian);
                //int[] rst = modbusTCP.ReadRegInt32(FuncCode.ReadHoldingRegisters, 10, 1, Endian.LittleEndian);

                //float[] fst = modbusTCP.ReadReg32Float(FuncCode.ReadHoldingRegisters,8,1,Endian.BigEndian);
                //float[] fst = modbusTCP.ReadReg32Float(FuncCode.ReadHoldingRegisters, 8, 1, Endian.LittleEndian);

            }
            #endregion

        }

        #region 连接
        /// <summary>
        /// 连接到ModbusTCP服务器
        /// </summary>
        private void Connect()
        {
            socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(IPAddress.Parse("127.0.0.1"), 502);
        }
        #endregion

        #region 属性值改变通知
        public event PropertyChangedEventHandler? PropertyChanged;

        /// <summary>
        /// 属性值改变通知
        /// </summary>
        /// <param name="propName"></param>
        private void PropChanged(string propName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        }
        #endregion

        #region 三个输出状态
        private bool outputStatus0;

        public bool OutputStatus0
        {
            get { return outputStatus0; }
            set
            {
                outputStatus0 = value;
                PropChanged("OutputStatus0");  // 属性值改变通知UI更新
            }
        }

        private bool outputStatus1;

        public bool OutputStatus1
        {
            get { return outputStatus1; }
            set
            {
                outputStatus1 = value;
                PropChanged("OutputStatus1");  // 属性值改变通知UI更新
            }
        }

        private bool outputStatus2;

        public bool OutputStatus2
        {
            get { return outputStatus2; }
            set
            {
                outputStatus2 = value;
                PropChanged("OutputStatus2");  // 属性值改变通知UI更新
            }
        }
        /// <summary>
        /// 读取三个状态输出
        /// </summary>
        private void ReadOutputStatus()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                bool[] result = modbusTCP.ReadBools(FuncCode.ReadCoils, 0, 3);
                OutputStatus0 = result[0];
                OutputStatus1 = result[1];
                OutputStatus2 = result[2];
            }
        }

        private void cb0_Click(object sender, RoutedEventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleCoil(0, OutputStatus0);
            }
        }

        private void cb1_Click(object sender, RoutedEventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleCoil(1, OutputStatus1);
            }
        }

        private void cb2_Click(object sender, RoutedEventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleCoil(2, OutputStatus2);
            }
        }

        #endregion

        #region 数字量输入
        private void ReadInputStatus()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                bool[] result = modbusTCP.ReadBools(FuncCode.ReadDiscreteInputs, 0, 3);

                if (result[0])
                {
                    BorderLight0.Background = new SolidColorBrush(Colors.Red);
                }
                else
                {
                    BorderLight0.Background = new SolidColorBrush(Colors.LightGray);
                }

                if (result[1])
                {
                    BorderLight1.Background = new SolidColorBrush(Colors.Red);
                }
                else
                {
                    BorderLight1.Background = new SolidColorBrush(Colors.LightGray);
                }

                if (result[2])
                {
                    BorderLight2.Background = new SolidColorBrush(Colors.Red);
                }
                else
                {
                    BorderLight2.Background = new SolidColorBrush(Colors.LightGray);
                }
            }
        }
        #endregion

        #region 模拟量输出 操作
        private void ReadOutputNum()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                short[] result = modbusTCP.ReadReg16(FuncCode.ReadHoldingRegisters, 0, 4);
                sVar0.Value = result[0];
                sVar1.Value = result[1];
                sVar2.Value = result[2];
                sVar3.Value = result[3];
            }
        }

        private void sVar0_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleReg(0, (short)sVar0.Value);
            }
        }

        private void sVar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleReg(1, (short)sVar1.Value);
            }
        }

        private void sVar2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleReg(2, (short)sVar2.Value);
            }
        }

        private void sVar3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleReg(3, (short)sVar3.Value);
            }
        }
        #endregion

        #region 模拟量的输入
        private void ReadInputNum()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                short[] result = modbusTCP.ReadReg16(FuncCode.ReadInputRegisters, 0, 4);
                txtInputReg0.Text = result[0].ToString();
                txtInputReg1.Text = result[1].ToString();
                txtInputReg2.Text = result[2].ToString();
                txtInputReg3.Text = result[3].ToString();
            }
        }
        #endregion

        #region 数字类型 操作
        private void ReadFloat()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                float[] results = modbusTCP.ReadReg32Float(FuncCode.ReadHoldingRegisters, 8, 1, Endian.BigEndian);
                txtFloat.Text = results[0].ToString();
            }
        }

        private void txtFloat_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteMultipleReg32Float(8, [float.Parse(txtFloat.Text)], Endian.BigEndian);
            }
        }

        private void ReadInt()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                int[] results = modbusTCP.ReadRegInt32(FuncCode.ReadHoldingRegisters, 10, 1, Endian.BigEndian);
                txtInt.Text = results[0].ToString();
            }
        }

        private void txtInt_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteMultipleReg32Int(10, [int.Parse(txtInt.Text)], Endian.BigEndian);
            }
        }

        private void ReadShort()
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                short[] results = modbusTCP.ReadReg16(FuncCode.ReadHoldingRegisters, 12, 1);
                txtShort.Text = results[0].ToString();
            }
        }

        private void txtShort_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                if (modbusTCP == null)
                {
                    modbusTCP = new ModbusTCP(socket);
                }

                modbusTCP.WriteSingleReg(12, short.Parse(txtShort.Text));
            }
        }

        #endregion

    }
}
